package com.okaysoft.ofb

import org.springframework.dao.DataIntegrityViolationException
import grails.converters.JSON

class DeviceController {

    def sysService
    def formworkService

    static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

    def index() {
        redirect(action: "list", params: params)
    }

    def list() {
    }

    def listJson() {
        params.max = Math.min(params.rows ? params.int('rows') : 10, 100)
        params.page = params.page ? params.int('page') : 0
        params.offset = (params.page - 1) * params.max
        def areaId = params.areaId
        if (!areaId) {
            render([rows:[],total:0] as JSON)
        }
        def total =  0
        def devices
        if (params.device_name){
            def query = Device.where {
                (name ==~ "%${params.device_name}%" || code ==~ "%${params.device_name}%")
            }
            total = query.count()
            devices = query.list(params)
        }else{
            total =  areaId?Device.countByArea(Area.get(areaId)):0
            devices = areaId?Device.findAllByArea(Area.get(areaId),params):[]
        }

        devices = devices.collect {device->
            [id:device.id,name:device.name,code: device.code,'location.addr':device?.location?.addr,
            'location.latitude':device?.location?.latitude,'location.longitude':device?.location?.longitude,
                    'location.installation':device?.location?.installation,description:device.description,
                    model:device?.model,factory:device.factory,'capacity.nominal':device?.capacity?.nominal,
                    'capacity.actual':device?.capacity?.actual,status: device?.status?.name(),logo:device.logo,mode:device?.mode?.name(),formworkId:device?.formwork?.id,formworkName:device?.formwork?.name]
        }

        render([rows:devices,total:total] as JSON)
    }

    def save() {
        def zg = params.ter_zg
        def px = params.ter_px
        def deviceInstance
        if (params.id) {
            deviceInstance = Device.get(params.id)
        }
        if (!deviceInstance) {
            deviceInstance = new Device()
        }

        deviceInstance.properties = params
        if (params.status) {
            deviceInstance.status = Device.Status."${params.status}"

        } 
        if (params.mode){
            deviceInstance.mode = Device.Mode."${params.mode}"

        }

        def area = Area.get(params.areaId)
        if (area){
            deviceInstance.area = area
        }

        /*if (!deviceInstance.save(flush: true)) {
            def failure = [status: 0,msg:message(code: 'device.save.failure.label', default: 'Save failure')] as JSON
            render(failure.toString())
            return
        }*/
        def zgs = []
        def pxs = []
        if(zg){
            zgs = zg.tokenize(',')
        }
        if(px){
            pxs = px.tokenize(',')
        }
        try{
            sysService.saveDevice(deviceInstance,zgs,pxs)

        }catch (RuntimeException e){
            def failure = [status: 0,msg:message(code: 'device.save.failure.label', default: 'Save failure')] as JSON
            render(failure.toString())
            return
        }

        def succ = [status: 1,msg:message(code: 'device.save.success.label', default: 'Save success')] as JSON
        render(succ.toString())
    }

    def show() {
        def deviceInstance = Device.get(params.id)
        if (!deviceInstance) {
			flash.message = message(code: 'default.not.found.message', args: [message(code: 'device.label', default: 'Device'), params.id])
        }

        [deviceInstance: deviceInstance]
    }

    def saveTerminal() {
        def tt
        def dn = params.deviceName
        def dt = params.deviceTerminal
        if (dn || dt) {
            def ter = dt?Terminal.findByNumber(dt):null
            def device = ter?.device
            if (device?.name != dn?.trim()) {
                def failure = [status: 2,msg:message(code: 'default.save.failure.message', default: 'Save failure')] as JSON
                render(failure.toString())
                return
            }
        }

        try {
            
            tt = sysService.saveTerminal(params)
        } catch (RuntimeException e) {
            log.error(e.message,e)
            def failure = [status: 0,msg:message(code: 'default.save.failure.message', default: 'Save failure')] as JSON
            render(failure.toString())
            return
        }
        def succ = [status: 1,tid: tt?.id, msg:message(code: 'default.save.success.message', default: 'Save success')] as JSON
        render(succ.toString())
    }

    def terminalObj() {
        def area = params.area
        def deviceId = params.deviceId 
        def terId = params.terId
        def device = Device.get(deviceId as Long)
        if (!device) {
            render("")
            return
        }

        def ter =Terminal.createCriteria().get {
            eq('device',device)
            eq('terId',terId as String)
        }
        if(!ter){
            ter = new Terminal()
            ter.area = area
            ter.device = device
            ter.terId = terId
            //ter.number=terId
           // ter.code = terId
            def tids = terId.tokenize('_')
            if (tids){
                ter.letter=tids[1]
                ter.letterNumber=tids[2]
            }
        }
        def parentTerminal
        def ts =[]
        //如果为配线端子，上行为该箱子的主干端子
        //if (ter.backboneWiring == Terminal.BackboneWiring.WIRING){
        //    parentTerminal = Terminal.findByDeviceAndBackboneWiring(device,Terminal.BackboneWiring.BACKBONE)
       // } else{
            def parentTer = ter?.superiorTerminal
            if (parentTer){
                //def pns = parentTer.tokenize('-')
                //def parentDeivceCode = pns[0]
                //def device1 = Device.findByCode(parentDeivceCode)
                parentTerminal = Terminal.findByNumber(parentTer)//findByDeviceAndTerId(device1,pns[1])
            }

       //}
        if (ter.id && ter){
            ///def parentCode = "${device.code}-${ter.terId}"
            ts = Terminal.findAllBySuperiorTerminal(ter.number)
        }
        if (parentTerminal){
            ts += Terminal.findAllBySuperiorTerminal(parentTerminal.number)
        }
        
        ts.sort {
            it.jumperPort
        }

        render(view: 'terminal',model: [terminal:ter,upTerminal:parentTerminal?:ter,downTerminals:ts])
    }

    def getTerminal() {
        def area = params.area
        def deviceId = params.deviceId
        if (!deviceId) {
            render("")
            return
        }
        def device = Device.get(deviceId as Long)
        if (!device) {
            render("")
            return
        }
        def ts 
        if (!area) {
            ts = Terminal.findAllByDevice(device)
        } else{
            ts = Terminal.findAllByAreaAndDevice(area as String,device)
        }
        if (!ts) {
            render("")
            return
        }
        ts = ts.collect {t->
            def caption = t.terId
            caption = caption.replace(area+'_','')
            [ID: t.id,Caption:caption,Title:t.code,Status:((t.status?.id ||t.status?.id==0)?t.status?.id:(t.vip?4:'1')),ZP:t.backboneWiring?.id]
        }
        def result = [ID:area,Caption:area,Ports:ts]  as JSON
        render(result.toString())
    }


    def showTerminal() {
         def ts = params.a
         ts = ts.collect {t->
             Terminal.get(t)
             
         }
         ts = ts as JSON
        render(ts.toString())
    }

    def delete() {
        def deviceInstance = Device.get(params.id)
        if (!deviceInstance) {
            def notfound = [status: 0, msg:  message(code: 'default.not.found.message', args: [message(code: 'device.label', default: 'Device'), params.id])] as JSON
            render(notfound.toString())
            return
        }

        try {
            sysService.removeDevice(deviceInstance)
            def succ = [status: 1, msg:  message(code: 'default.deleted.message', args: [message(code: 'device.label', default: 'Device'), params.id])] as JSON
            render(succ.toString())

        }
        catch (DataIntegrityViolationException e) {
            def failure = [status: 0, msg:  message(code: 'default.not.deleted.message', args: [message(code: 'device.label', default: 'Device'), params.id])] as JSON
            render(failure.toString())

        }
    }

    def areaTreeJson() {
        def at = sysService.areaTreeJson(null) as JSON
        render at.toString()
    }

    def saveArea() {
        def area 
        if (params.id) {
            area = Area.get(params.id)
        }
        if(!area) {
            area = new Area()
        }
        area.properties = params

        if (!area.save(flush: true)) {
            def failure = [status: 0,msg:message(code: 'default.save.failure.message', default: 'Save failure')] as JSON
            render(failure.toString())
            return
        }

        def succ = [status: 1,msg:message(code: 'default.save.success.message', default: 'Save success')] as JSON
        render(succ.toString())
    }

    def areaDelete() {
        def areaInstance = Area.get(params.id)
        if (!areaInstance) {
            def notfound = [status: 0, msg:  message(code: 'default.not.found.message', args: [message(code: 'area.label', default: 'Area'), params.id])] as JSON
            render(notfound.toString())
            return
        }

        try {
            areaInstance.delete(flush: true)
            def succ = [status: 1, msg:  message(code: 'default.deleted.message', args: [message(code: 'area.label', default: 'Area'), params.id])] as JSON
            render(succ.toString())

        }
        catch (DataIntegrityViolationException e) {
            def failure = [status: 0, msg:  message(code: 'default.not.deleted.message', args: [message(code: 'area.label', default: 'Area'), params.id])] as JSON
            render(failure.toString())

        }
    }
    
    def terminal() {
        if (!params.id) {
            render("")
             return
        }
        def fcd = [latitude:'0',longitude:'0']
        def device = Device.get(params.id)
        if (!device){
            fcd = fcd  as JSON
            render(fcd.toString())
            return
        }
        fcd['latitude'] = device?.location?.latitude
        fcd['longitude'] = device?.location?.longitude
        def formwork = device.formwork
        if (!formwork){
            fcd = fcd  as JSON
            render(fcd.toString())
            return
        }
        fcd << formworkService.formworkCompositionData(formwork)

        fcd = fcd  as JSON
        render(fcd.toString())
        return
    }

    def formworkTreeData() {
        def id = params.long("id")
        def formwork = Formwork.get(id)
        def fcd = [:]
        if (!formwork){
            fcd = fcd  as JSON
            render(fcd.toString())
            return
        }
        fcd = formworkService.formworkCompositionData(formwork)

        fcd = fcd  as JSON
        render(fcd.toString())
        return
    }

    def saveDeviceFormwork() {
        def formworkId = params.formworkId
        def deviceId = params.deviceId
        if (!formworkId || !deviceId) {
            def notfound = [status: 0, msg:  message(code: 'default.not.found.message', args: [message(code: 'area.label', default: 'Area'), params.id])] as JSON
            render(notfound.toString())
            return
        }
        def formwork = Formwork.get(formworkId)
        if (!formwork) {
            def notfound = [status: 0, msg:  message(code: 'default.not.found.message', args: [message(code: 'area.label', default: 'Area'), params.id])] as JSON
            render(notfound.toString())
            return
        }
       
        def device = Device.get(deviceId)
        if (!device) {
            def notfound = [status: 0, msg:  message(code: 'default.not.found.message', args: [message(code: 'area.label', default: 'Area'), params.id])] as JSON
            render(notfound.toString())
            return
        }
        if(device.formwork && device.formwork.id == formwork.id){
            def succ = [status: 2,msg:message(code: 'default.save.success.message', default: 'Save success')] as JSON
            render(succ.toString())
            return
        }
        device.formwork = formwork
        if (!device.save(flush: true)) {
            def notfound = [status: 0, msg:  message(code: 'default.not.found.message', args: [message(code: 'area.label', default: 'Area'), params.id])] as JSON
            render(notfound.toString())
            return
        }
        //删除已经有的端子信息
        def ts = Terminal.findAllByDevice(device)
        ts.each {t->
            TerminalClientUser.removeAll(t)
        }
        Terminal.executeUpdate("delete from Terminal where device=:device",[device:device])
        //Task.executeQuery("delete from Task where device=:device",[device,device])
        def succ = [status: 1,msg:message(code: 'default.save.success.message', default: 'Save success')] as JSON
        render(succ.toString())
    }
    
    def route() {
        def number = params.number
        if(!number){
            render(view:'route',model:[routes:[]])
            return
        }

        def terminal = Terminal.findByNumber(number)
        if(!terminal){
            render(view:'route',model:[routes:[]])
            return
        }
        def list = sysService.getUpNetRouter(terminal,true)//sysService.getNetRouter(device,[])
        def downList = sysService.getDowngetNetRouter(terminal)//.getDowngetNetRouter(device,[])
        [routes:list+downList]
    }
    
    def getClientUsersByTerId(){
        def deviceId = params.deviceId
        def terId = params.terId
        def device = Device.get(deviceId as Long)
        def terminal = Terminal.findByDeviceAndTerId(device,terId)
        if (!terminal) {
            render("")
            return
        }
        def clientUser = terminal.clientUsers
        if(!clientUser){
            render("")
            return
        }
        def clientUsers = clientUser.tokenize(',');
        def cus = clientUsers.collect {cu->
            ClientUser.get(cu as Long)
        }
        
        render((cus as JSON)as String )
    }
    
    def cu(){
        params.max = Math.min(params.rows ? params.int('rows') : 10, 100)
        params.page = params.page ? params.int('page') : 0
        params.offset = (params.page - 1) * params.max
        params.sort = "id"
        params.order = "desc"
        def terminaId = params.id
        def device = Device.get(params.deviceId as Long)
        def terminal = Terminal.findByDeviceAndTerId(device,terminaId,params)
        def clientUsers = terminal?.clientUsers
        clientUsers = clientUsers.collect {cu->
            def cut = cu.clientUserTypes
            cut = cut.collect {c->
                c.type.label
            }
            [id: cu.id,text:cu.name,name:cu.name,vip:cu.vip,type:cut,code: cu.code,description: cu.description,'client.id':cu.client?.id,clientId:cu.client?.id,clientName:cu.client?.name]
        }
        render([rows:clientUsers?:[],total:clientUsers?clientUsers.size():0] as JSON)
    }
    
    def saveClientUser(){
        def device = Device.get(params.deviceId as Long)
        def terminal = Terminal.findByDeviceAndTerId(device,params.terId)
        def clientUser = ClientUser.get(params.id as Long)
        def tc = TerminalClientUser.findByClientUser(clientUser)
        if(tc){
            def succ
            if (tc.terminal.id == terminal.id){
                succ = [status: 3,deviceName:tc.terminal?.device?.name,terId:tc.terminal?.terId] as JSON
            } else{
                succ = [status:2,deviceName:tc.terminal?.device?.name,terId:tc.terminal?.terId] as JSON
            }
            render(succ.toString())
            return
        }

        def succ
        try {
            sysService.saveTerminalClientUser(terminal,clientUser)
            succ = [status: 1,msg:message(code: 'default.save.success.message', default: 'Save success')] as JSON
        } catch (RuntimeException e) {
            log.error(e.message,e)
            succ = [status: 0,msg:message(code: 'default.save.failure.message', default: 'Save success')] as JSON
        }
        render(succ.toString())
    }

    def removeTcu(){
        def device = Device.get(params.deviceId as Long)
        def terminal = Terminal.findByDeviceAndTerId(device,params.terId)
        def clientUser = ClientUser.get(params.id as Long)
        def succ
        try {
            sysService.removeTerminalClientUser(terminal,clientUser)
            succ = [status: 1,msg:message(code: 'default.save.success.message', default: 'Save success')] as JSON
        } catch (RuntimeException e) {
            log.error(e.message,e)
            succ = [status: 0,msg:message(code: 'default.save.failure.message', default: 'Save success')] as JSON
        }
        render(succ.toString())
    }

    def formworkTreeJson() {
        def ft = formworkService.formworkTreeJson(null) as JSON
        render ft.toString()
    }
}
